#include "SquareThread.h"
#include <QDebug>
#include <QTimer>

// ========== SquareWorker 实现 ==========
SquareWorker::SquareWorker(QObject *parent)
    : QObject(parent)
    , m_shouldStop(false)
{
}

void SquareWorker::doWork(const QPoint &topLeft, int sideLength)
{
    qDebug() << "SquareWorker::doWork 开始 - topLeft:" << topLeft << "sideLength:" << sideLength;
    m_shouldStop = false;
    
    // 检查参数有效性
    if (sideLength <= 0) {
        qWarning() << "SquareWorker: sideLength 无效:" << sideLength;
        emit workFinished();
        return;
    }
    
    // 方形的四个顶点
    QPoint points[4] = {
        topLeft,
        QPoint(topLeft.x() + sideLength, topLeft.y()),
        QPoint(topLeft.x() + sideLength, topLeft.y() + sideLength),
        QPoint(topLeft.x(), topLeft.y() + sideLength)
    };

    int pointCount = 0;
    // 沿着每条边绘制点
    for (int i = 0; i < 4 && !m_shouldStop && !QThread::currentThread()->isInterruptionRequested(); ++i) {
        QPoint start = points[i];
        QPoint end = points[(i + 1) % 4];
        
        // 使用浮点数计算避免整数除法精度问题
        double dx = static_cast<double>(end.x() - start.x()) / sideLength;
        double dy = static_cast<double>(end.y() - start.y()) / sideLength;

        for (int j = 0; j <= sideLength && !m_shouldStop && !QThread::currentThread()->isInterruptionRequested(); ++j) {
            int x = start.x() + static_cast<int>(dx * j);
            int y = start.y() + static_cast<int>(dy * j);
            emit pointGenerated(QPoint(x, y));
            pointCount++;
            QThread::msleep(5); // 控制绘制速度
        }
    }
    
    qDebug() << "SquareWorker: 画方完成，共生成" << pointCount << "个点";
    emit workFinished();
}

// ========== SquareThread 实现 ==========
SquareThread::SquareThread(QObject *parent)
    : QObject(parent)
    , m_topLeft(0, 0)
    , m_sideLength(0)
    , m_thread(nullptr)
    , m_worker(nullptr)
    , m_running(false)
    , m_workStarted(false)
{
    // 创建工作线程和工作对象
    m_thread = new QThread(this);
    m_worker = new SquareWorker();
    
    // 将工作对象移动到工作线程
    m_worker->moveToThread(m_thread);
    
    // 连接信号槽：工作对象 -> 主对象
    connect(m_worker, &SquareWorker::pointGenerated, this, &SquareThread::onPointGenerated, Qt::QueuedConnection);
    connect(m_worker, &SquareWorker::workFinished, this, &SquareThread::onWorkerFinished, Qt::QueuedConnection);
    
    // 连接线程信号：线程启动后开始工作
    connect(m_thread, &QThread::started, this, &SquareThread::onThreadStarted);
    
    // 线程结束时清理工作对象（线程对象由主对象管理，不自动删除）
    connect(m_thread, &QThread::finished, m_worker, &QObject::deleteLater);
}

SquareThread::~SquareThread()
{
    stop();
    if (m_thread) {
        if (m_thread->isRunning()) {
            m_thread->quit();
            m_thread->wait(3000);
        }
    }
}

void SquareThread::start()
{
    // 只检查 running 状态和 thread 是否存在，不检查 worker（因为后面会重新创建）
    if (m_running || !m_thread) {
        qDebug() << "SquareThread: 无法启动 - m_running:" << m_running << "m_thread:" << (m_thread != nullptr);
        return;
    }
    
    // 如果线程已经在运行，先停止并等待完成
    if (m_thread->isRunning()) {
        qDebug() << "SquareThread: 线程正在运行，先停止";
        stop();
        if (!m_thread->wait(2000)) {
            qWarning() << "SquareThread: 线程未在2秒内停止";
            return;
        }
    }
    
    // 确保线程已经完全停止（finished）
    if (m_thread->isRunning()) {
        qWarning() << "SquareThread: 线程仍在运行，无法启动";
        return;
    }
    
    // 重新创建工作对象（因为可能已被删除，例如绘制完成后）
    if (!m_worker) {
        qDebug() << "SquareThread: 重新创建工作对象";
        m_worker = new SquareWorker();
        m_worker->moveToThread(m_thread);
        connect(m_worker, &SquareWorker::pointGenerated, this, &SquareThread::onPointGenerated, Qt::QueuedConnection);
        connect(m_worker, &SquareWorker::workFinished, this, &SquareThread::onWorkerFinished, Qt::QueuedConnection);
        connect(m_thread, &QThread::finished, m_worker, &QObject::deleteLater);
        
        // 断开旧连接（如果存在）并重新连接 QThread::started 信号
        disconnect(m_thread, &QThread::started, this, &SquareThread::onThreadStarted);
        connect(m_thread, &QThread::started, this, &SquareThread::onThreadStarted);
    }
    
    // 检查参数有效性
    if (m_sideLength <= 0) {
        qWarning() << "SquareThread: sideLength 无效，无法启动:" << m_sideLength;
        return;
    }
    
    m_running = true;
    m_workStarted = false;  // 重置工作开始标志
    emit runningChanged();
    
    // 启动线程（onThreadStarted会在线程启动后自动调用）
    qDebug() << "SquareThread: 准备启动线程 - m_thread:" << m_thread 
             << "m_worker:" << m_worker << "m_sideLength:" << m_sideLength
             << "thread finished:" << m_thread->isFinished();
    m_thread->start();
    
    // 等待线程启动（最多等待100ms）
    int waitCount = 0;
    while (!m_thread->isRunning() && waitCount < 10) {
        QThread::msleep(10);
        waitCount++;
    }
    
    qDebug() << "SquareThread: 启动画方线程，线程状态 - isRunning:" << m_thread->isRunning() 
             << "waitCount:" << waitCount;
    
    // 如果线程启动失败
    if (!m_thread->isRunning()) {
        qWarning() << "SquareThread: 线程启动失败";
        m_running = false;
        m_workStarted = false;
        emit runningChanged();
        return;
    }
    
    // 备用机制：如果信号没有触发，直接调用 onThreadStarted
    // 使用 QTimer::singleShot 延迟调用，确保线程事件循环已启动
    // 添加 m_workStarted 检查，防止重复调用
    QTimer::singleShot(50, this, [this]() {
        if (m_running && !m_workStarted && m_worker && m_thread->isRunning()) {
            qDebug() << "SquareThread: 备用机制 - 直接调用 onThreadStarted";
            onThreadStarted();
        }
    });
}

void SquareThread::stop()
{
    if (!m_thread) {
        return;
    }
    
    // 无论 m_running 是什么，只要线程在运行就停止它
    if (m_thread->isRunning()) {
        qDebug() << "SquareThread: 停止线程 - m_running:" << m_running;
        
        // 通知工作对象停止
        if (m_worker) {
            QMetaObject::invokeMethod(m_worker, "requestStop", Qt::QueuedConnection);
        }
        
        m_thread->requestInterruption();
        m_thread->quit();
        if (!m_thread->wait(1000)) {
            qWarning() << "SquareThread: 线程未在1秒内停止，强制终止";
            m_thread->terminate();
            m_thread->wait(500);
        }
    }
    
    // 更新运行状态
    if (m_running) {
        m_running = false;
        m_workStarted = false;  // 重置工作开始标志
        emit runningChanged();
    }
    
    qDebug() << "SquareThread: 停止画方线程完成 - isRunning:" << (m_thread ? m_thread->isRunning() : false);
}

void SquareThread::onWorkerFinished()
{
    qDebug() << "SquareThread: onWorkerFinished 被调用 - 当前 m_running:" << m_running;
    
    // 停止线程
    if (m_thread && m_thread->isRunning()) {
        qDebug() << "SquareThread: 工作完成，停止线程";
        m_thread->quit();
        if (!m_thread->wait(1000)) {
            qWarning() << "SquareThread: 线程未在1秒内停止，强制终止";
            m_thread->terminate();
            m_thread->wait(500);
        }
    }
    
    m_running = false;
    m_workStarted = false;  // 重置工作开始标志
    emit runningChanged();
    emit finished();
    qDebug() << "SquareThread: 状态已更新 - m_running:" << m_running << "running():" << running();
    // 标记worker为null，因为会被deleteLater删除
    m_worker = nullptr;
    qDebug() << "SquareThread: 工作完成";
}

void SquareThread::onThreadStarted()
{
    // 防止重复调用
    if (m_workStarted) {
        qDebug() << "SquareThread: onThreadStarted 已被调用过，跳过重复调用";
        return;
    }
    
    qDebug() << "SquareThread: 线程已启动，开始调用doWork";
    
    // 检查 worker 是否存在
    if (!m_worker) {
        qWarning() << "SquareThread: m_worker 为 nullptr，无法调用 doWork";
        return;
    }
    
    // 标记工作已开始，防止重复调用
    m_workStarted = true;
    
    bool success = QMetaObject::invokeMethod(m_worker, "doWork", Qt::QueuedConnection,
                                             Q_ARG(QPoint, m_topLeft),
                                             Q_ARG(int, m_sideLength));
    qDebug() << "SquareThread: invokeMethod结果:" << success 
             << "topLeft:" << m_topLeft << "sideLength:" << m_sideLength;
    
    if (!success) {
        qWarning() << "SquareThread: invokeMethod 失败";
        m_workStarted = false;  // 如果调用失败，重置标志
    }
}

void SquareThread::onPointGenerated(const QPoint &pt)
{
    qDebug() << "SquareThread::onPointGenerated 收到点:" << pt;
    emit squarePoint(pt);
}

